<html>
<head><meta charset="utf-8"><title>parallel/concurrent blocks for async · t-lang · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/index.html">t-lang</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/parallel.2Fconcurrent.20blocks.20for.20async.html">parallel/concurrent blocks for async</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="238526412"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/parallel/concurrent%20blocks%20for%20async/near/238526412" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/parallel.2Fconcurrent.20blocks.20for.20async.html#238526412">(May 12 2021 at 18:57)</a>:</h4>
<p>This grew out of the <a href="#narrow/stream/213817-t-lang/topic/.60for.20await.60.20interest"><code>for await</code> topic</a>, but I think it's worth bringing up separately. If you ignore for a moment the differences between runtimes and assume we have a portable way to spawn tasks, would it be reasonable for us to have something like:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="n">parallel</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">xv</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">x</span><span class="p">().</span><span class="k">await</span><span class="o">?</span><span class="p">;</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">yv</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">y</span><span class="p">().</span><span class="k">await</span><span class="o">?</span><span class="p">;</span><span class="w"></span>
<span class="w">    </span><span class="n">func</span><span class="p">(</span><span class="n">xv</span><span class="p">,</span><span class="w"> </span><span class="n">yv</span><span class="p">).</span><span class="k">await</span><span class="o">?</span><span class="p">;</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<p>This would await x and y in parallel because they don't have data dependencies, and then call func and await the result.</p>



<a name="238526423"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/parallel/concurrent%20blocks%20for%20async/near/238526423" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/parallel.2Fconcurrent.20blocks.20for.20async.html#238526423">(May 12 2021 at 18:57)</a>:</h4>
<p>This wouldn't affect the internals of x and y in any way; any awaits within x and y would still happen in series unless x or y themselves used <code>parallel</code>.</p>



<a name="238526521"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/parallel/concurrent%20blocks%20for%20async/near/238526521" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/parallel.2Fconcurrent.20blocks.20for.20async.html#238526521">(May 12 2021 at 18:58)</a>:</h4>
<p>(Also, that <em>might</em> be spelled <code>parallel { ... }.await?</code>.)</p>



<a name="238526742"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/parallel/concurrent%20blocks%20for%20async/near/238526742" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/parallel.2Fconcurrent.20blocks.20for.20async.html#238526742">(May 12 2021 at 18:59)</a>:</h4>
<p>This would desugar to <code>join</code> at a minimum. Let's leave aside for the moment the question of also spawning tasks to allow parallelism across CPUs/threads.</p>



<a name="238530147"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/parallel/concurrent%20blocks%20for%20async/near/238530147" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/parallel.2Fconcurrent.20blocks.20for.20async.html#238530147">(May 12 2021 at 19:23)</a>:</h4>
<p>I'm not sure how I feel about the automatic data dependency analysis for this.</p>
<p>Any chance that there are some common patterns of it that would be helpful but less magical?  Your example there makes me think of a "parallel <code>let in</code>" where all the <code>let</code>s are assumed independent, so are automatically <code>join!</code>ed before calling the trailing expression.</p>
<p>(<code>let in</code> as in the SML-style <code>let x = foo() in x + x</code>, though in a more Rusty form.)</p>



<a name="238533035"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/parallel/concurrent%20blocks%20for%20async/near/238533035" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/parallel.2Fconcurrent.20blocks.20for.20async.html#238533035">(May 12 2021 at 19:46)</a>:</h4>
<p>So, "parallel let" versus allowing fully general statements?</p>



<a name="238533856"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/parallel/concurrent%20blocks%20for%20async/near/238533856" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dirkjan Ochtman <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/parallel.2Fconcurrent.20blocks.20for.20async.html#238533856">(May 12 2021 at 19:52)</a>:</h4>
<p>This <code>let in</code> sounds a bit like Python's context managers, maybe?</p>



<a name="238546456"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/parallel/concurrent%20blocks%20for%20async/near/238546456" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/parallel.2Fconcurrent.20blocks.20for.20async.html#238546456">(May 12 2021 at 21:19)</a>:</h4>
<p><span class="user-mention silent" data-user-id="239881">Josh Triplett</span> <a href="#narrow/stream/213817-t-lang/topic/parallel.2Fconcurrent.20blocks.20for.20async/near/238533035">said</a>:</p>
<blockquote>
<p>So, "parallel let" versus allowing fully general statements?</p>
</blockquote>
<p>That seems like a better summary phrasing, yeah.</p>
<p>(And it'd be doable with a simple <code>macro_rules!</code> macro, which is convenient...)</p>



<a name="238725027"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/parallel/concurrent%20blocks%20for%20async/near/238725027" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Matthias247 <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/parallel.2Fconcurrent.20blocks.20for.20async.html#238725027">(May 14 2021 at 06:37)</a>:</h4>
<p>What is wrong with just using <code>FuturesUnordered</code> for doing that? It's explicit - you tell it what needs to run in parallel and what not. And it safes you from all questions around mutability. It likely also have the same cancel semantics than your block (where all of them might have issues if the functions you call <code>spawn</code> something).</p>



<a name="238725108"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/parallel/concurrent%20blocks%20for%20async/near/238725108" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Matthias247 <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/parallel.2Fconcurrent.20blocks.20for.20async.html#238725108">(May 14 2021 at 06:38)</a>:</h4>
<p>I think Swift hat semantics that were along what you are looking into, and they desuraged into a <code>TaskGroup</code> (structured concurrency container - like <code>FuturesUnordered</code> - but with async cancellation support). But I haven't checked the latest proposals and whether they actually kept the implement conversion</p>



<a name="238725292"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/parallel/concurrent%20blocks%20for%20async/near/238725292" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Matthias247 <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/parallel.2Fconcurrent.20blocks.20for.20async.html#238725292">(May 14 2021 at 06:41)</a>:</h4>
<p>A quick can says the might have nixed the implicit version: <a href="https://github.com/apple/swift-evolution/blob/main/proposals/0304-structured-concurrency.md">https://github.com/apple/swift-evolution/blob/main/proposals/0304-structured-concurrency.md</a></p>



<a name="238794446"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/parallel/concurrent%20blocks%20for%20async/near/238794446" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/parallel.2Fconcurrent.20blocks.20for.20async.html#238794446">(May 14 2021 at 16:38)</a>:</h4>
<p><span class="user-mention silent" data-user-id="204219">Matthias247</span> <a href="#narrow/stream/213817-t-lang/topic/parallel.2Fconcurrent.20blocks.20for.20async/near/238725027">said</a>:</p>
<blockquote>
<p>What is wrong with just using <code>FuturesUnordered</code> for doing that? It's explicit</p>
</blockquote>
<p>That's exactly what's wrong with it. :)</p>
<p>More seriously, the advantage of a syntax like that would be that you can write code that <em>looks</em> like straight-line async-await code, and have the compiler infer the dependencies for you. There are already ways to specify what runs in parallel (and I'm not sure how FuturesUnordered would help for the kind of code I posted, seems like that'd just use join). It'd be nice to <em>not</em> have to specify.</p>



<a name="239284279"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/parallel/concurrent%20blocks%20for%20async/near/239284279" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/parallel.2Fconcurrent.20blocks.20for.20async.html#239284279">(May 18 2021 at 16:30)</a>:</h4>
<p>so I just did a mark all as read in this stream because I do that <em>but</em></p>



<a name="239284283"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/parallel/concurrent%20blocks%20for%20async/near/239284283" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/parallel.2Fconcurrent.20blocks.20for.20async.html#239284283">(May 18 2021 at 16:30)</a>:</h4>
<p>I really want to pursue ideas like this</p>



<a name="239284318"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/parallel/concurrent%20blocks%20for%20async/near/239284318" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/parallel.2Fconcurrent.20blocks.20for.20async.html#239284318">(May 18 2021 at 16:31)</a>:</h4>
<p>I want things like rayon etc to be kind of first-class</p>



<a name="239284329"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/parallel/concurrent%20blocks%20for%20async/near/239284329" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/parallel.2Fconcurrent.20blocks.20for.20async.html#239284329">(May 18 2021 at 16:31)</a>:</h4>
<p>I don't yet know what I think that means</p>



<a name="239305361"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/parallel/concurrent%20blocks%20for%20async/near/239305361" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> cuviper <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/parallel.2Fconcurrent.20blocks.20for.20async.html#239305361">(May 18 2021 at 18:44)</a>:</h4>
<p>sounds like openmp, but it depends on what you mean by "first class"</p>



<a name="239305434"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/parallel/concurrent%20blocks%20for%20async/near/239305434" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> cuviper <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/parallel.2Fconcurrent.20blocks.20for.20async.html#239305434">(May 18 2021 at 18:45)</a>:</h4>
<p>I <em>like</em> that rayon is "just" a library, not something special in rustc's eyes</p>



<a name="239321614"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/parallel/concurrent%20blocks%20for%20async/near/239321614" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/parallel.2Fconcurrent.20blocks.20for.20async.html#239321614">(May 18 2021 at 20:36)</a>:</h4>
<p>yeah, I'm not sure what I mean either. I generally like doing things in libraries.</p>



<a name="239338329"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/parallel/concurrent%20blocks%20for%20async/near/239338329" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/parallel.2Fconcurrent.20blocks.20for.20async.html#239338329">(May 18 2021 at 22:57)</a>:</h4>
<p>I wouldn't want to put too much in the language. I do think there's value in getting the compiler's help understanding data-dependencies.</p>



<a name="239338351"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/parallel/concurrent%20blocks%20for%20async/near/239338351" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/parallel.2Fconcurrent.20blocks.20for.20async.html#239338351">(May 18 2021 at 22:57)</a>:</h4>
<p>I'd hope for something that's just enough to capture those dependencies and otherwise desugar to normal futures that can run on any runtime library.</p>



<a name="239340798"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/parallel/concurrent%20blocks%20for%20async/near/239340798" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/parallel.2Fconcurrent.20blocks.20for.20async.html#239340798">(May 18 2021 at 23:22)</a>:</h4>
<p>the only thing is that there may be a need to have some syntax in async land</p>



<a name="239340848"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/parallel/concurrent%20blocks%20for%20async/near/239340848" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/parallel.2Fconcurrent.20blocks.20for.20async.html#239340848">(May 18 2021 at 23:22)</a>:</h4>
<p>to ensure that you create a scope and await it</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>